//
// Created by xwt
//
#include <httplib.h>
#include <functional>
#include <ab_process.hpp>
#include <ab_shm.hpp>
#include "agent_cfg.hpp"
#include "agent_types.hpp"
#include "coverageParser.hpp"

#ifndef AGENT_HTTP_SERVER_HPP
#define AGENT_HTTP_SERVER_HPP

namespace anbantech {
#define HTTP_METHOD_HEAD "HEAD"
#define HTTP_METHOD_POST "POST"
#define HTTP_METHOD_PUT "PUT"
#define HTTP_METHOD_GET "GET"
#define HTTP_METHOD_DELETE "DELETE"
#define HTTP_METHOD_PATCH "PATCH"

#define HTTP_CONTENT_TYPE_TEXT "text/plain"
#define HTTP_CONTENT_TYPE_JSON "application/json"

#define SHM_KEY          20181217

    using handler = std::function<void(const httplib::Request&,httplib::Response&)>;

    struct path_handler {
        std::string method;
        std::string path;
        handler     handle;
    };
    class http_server {
    public:
        http_server(const std::string& cfg_path);
        ~http_server();
        int init();

        void run();

    private:
        void add_path_handler(std::string method,std::string path,handler handle);

        void setup_routes();

        void handle_execution_responses(const httplib::Request& req, httplib::Response& res) ;
        void handle_run_execution(const httplib::Request& req, httplib::Response& res) ;
        void handle_update_execution(const httplib::Request& req, httplib::Response& res) ;
        void handle_get_execution(const httplib::Request& req, httplib::Response& res) ;
        void handle_readiness(const httplib::Request& req, httplib::Response& res) ;
        void handle_clean_fuzzing(const httplib::Request& req, httplib::Response& res) ;

        void handle_url_redirection(const httplib::Request& req, httplib::Response& res) ;
        void handle_url_ssrf(const httplib::Request& req, httplib::Response& res) ;
        void handle_not_found(const httplib::Request& req, httplib::Response& res);
        void handle_corpus_run(const httplib::Request& req, httplib::Response& res);

        int write_to_file(const std::string& filename, const std::string& content);
        char* get_localtime();


    private:
        int mPort;
        std::string mcfgPath;
        bool mbTargetCrashed;
        agent_cfg mCfg;
        agent_data mPayload;
        char** mEnvs;

        httplib::Server mServer;
        std::vector<path_handler> mPathHandler;

        ab_process mSubprocess;
        ab_shm mShm;

    };

} // anbantech

#endif //AGENT_HTTP_SERVER_HPP
